/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package fr.ove.palette.swing;

/**
 *
 * @author Mr.Sam
 */
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import fr.ove.palette.*;
import fr.ove.palette.events.*;

/**
* The palette.<BR>
* The palette throws @see PaletteEvent to the registered @see PaletteEventListener.<BR>
* These events contain a @see PaletteInfo object which contains relevant information for
* the listeners.
* <P>
* The palette can be made of objects which have the <CODE>addActionListener(ActionListener l)</CODE>.
* Only objects such as buttons are relevant in a palette, but if you want to add other kind of objects
* having the <CODE>addActionListener(ActionListener l)</CODE> method, what you have to do is the
* something like what is following:
* <UL>
* <LI>Palette palette = new Palette(...);</LI>
* <LI>MyStuff stuff = new MyStuff(...);  // Which extends java.awt.Component</LI>
* <LI>palette.getCorrespondance().put(stuff, new PalettreInfo(...));</LI>
* <LI>stuff.addActionListener(palette.getActionListener()); // MyStuff must implement this methods (at least)
* to send ActionEvent to objects which want to be informed of actions on it (such as button, ... see before)</LI>
* <LI>palette.add(stuff);</LI>
* </UL>
* Or you can subclass this class and implement your own </CODE>addStuffToPalette(...)</CODE> doing the
* given pice of code.<BR>
*
* @author © 1999 DIRAT Laurent
* @version 1.0  19/09/1999
*/
public class Palette extends JPanel {
    /**
    * The <CODE>ActionListener</CODE> of each button in the palette.<BR>
    * It is in charge of throwing an event with the <CODE>PaletteInfo</CODE>
    * corresponding to the button pressed, to the listener(s) of the palette.
    */
    private static ActionListener actionListener;
    
    /**
    * The correspondance between the button pressed in the palette and the information to send
    * to the listener(s) of the palette.<BR>
    * This hashtable has as key the button in the palette and as value, the @see PaletteInfo
    * corresponding to the button.
    */
    private Hashtable correspondance = new Hashtable();
    
    /**
    * The list of listeners of the palette
    */
    private Vector listeners = new Vector();
    
    /**
    * The contstructor.
    * @param constraint the constraint (<CODE>PaletteLayout.ROW_CONSTRAINT</CODE> or
    * <CODE>PaletteLayout.COLUMN_CONSTRAINT</CODE>) for ordering the components in the palette.
    * @param nbElement the number max of element allowed by row (resp. column) with the 
    * <CODE>PaletteLayout.ROW_CONSTRAINT</CODE> (resp. PaletteLayout.<CODE>COLUMN_CONSTRAINT</CODE>) constraint.
    */
    public Palette(byte constraint, int nbElement) {
        super();
        setLayout(new PaletteLayout(constraint, nbElement));
        
        actionListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Object src = e.getSource();
                PaletteEvent paletteEvent = new PaletteEvent(src);
                paletteEvent.setPaletteInfo((PaletteInfo) correspondance.get(src));
                firePaletteEvent(paletteEvent);
            }
        };
    }
    
    /**
    * Adds a button into the palette with the specified information (@see PaletteInfo).
    * @param button the button to add into the palette.
    * @param paletteInfo the specified palette information
    */
    public void addButtonToPalette(JButton button, PaletteInfo paletteInfo) {
        add(button);
        button.addActionListener(actionListener);
        correspondance.put(button, paletteInfo);
    }
    
    /**
    * Returns the correspondances (i.e. the hastable) of the stuff in the palette and their
    * associated relevant information to send to the listener of the instance.
    */
    public Hashtable getCorrespondance() {
        return correspondance;
    }
    
    /**
    * Returns the @see ActionListener share by the different instance of <CODE>Palette</CODE> which
    * is in charge of throwing @see PaletteEvent to all the listeners.
    */
    public ActionListener getActionListener() {
        return actionListener;
    }
    
    /**
    * Registers another listener to be informed of changes of the palette.
    * @param paletteListener a listener to add.
    */
    public void addPaletteListener(PaletteListener paletteListener) {
        listeners.addElement(paletteListener);
    }

    /**
    * Removes a listener.
    * @param paletteListener the listener to remove.
    */
    public void removePaletteListener(PaletteListener paletteListener) {
        listeners.removeElement(paletteListener);
    }

    /**
    * Fires a PaletteEvent event to registered listeners.
    * @param paletteEvent event encapsulating relevant information.
    */
    public void firePaletteEvent(PaletteEvent paletteEvent) {
        for (int i = 0; i < listeners.size(); i++)
          ((PaletteListener) listeners.elementAt(i)).consumePaletteEvent(paletteEvent);
    }
}
